perm filename TCPPAR.MAC[IP,SYS] blob
sn#680225 filedate 1982-10-14 generic text, type T, neo UTF8
;CWL:<403-TCP>TCPPAR.MAC.40303 29-Apr-82 7:42:16, Edit by CLYNN
; Add Max Segment Length option, TRLAK, TRLWN, options, etc
;<403-TCP>TCPPAR.MAC.40301 29-Jan-82 15:06:18, Edit by CLYNN
; Updated for TCP release 3
; Move JSYS-related definitions to MONSYM (via MONSYM.D4I)
; Add definition of PTVT parallel to that in TTTVDV.MAC for use by BG
UNIVER TCPPAR
SUBTTL TCP Parameters, William W. Plummer, 2Mar79
SEARCH INPAR,IMPPAR,PROLOG,MONSYM,MACSYM
SYN INBUG,TCPBUG ; Use Internet bug macro
; Make sure MNET switch = 0, if not defined
IFNDEF MNET,<MNET==0>
; Check consistency of IMPPAR with TCPPAR:
IF1 < IFDEF .TCPFM,<
IFN .TCPFM-6,<PRINTX % .TCPFM defined wrong in IMPPAR
.TCPFM==6
>
>
IFNDEF .TCPFM,<;;;PRINTX % .TCPFM not defined in IMPPAR
.TCPFM==6
>
>
; TCP Parameters:
MAXSEQ==1←↑D32 ;STG ; 32 bit sequence numbers
SEQMSK==MAXSEQ-1 ; Mask for doing mod MAXSEQ by AND op.
DEFINE MODSEQ(A)<TLZ A,(-MAXSEQ)>
CYCTIM==↑D<2*60*60> ;STG ; Network cycle time in seconds
;MLIFET==30*60 ; Assumed message lifetime in seconds
SNSTEP==MAXSEQ/CYCTIM ; A second's worth of sequence numbers
;SNMARG==MLIFET*SNSTEP/2 ; Half width of forbidden zone
; TCP Header (indexed by TPKT):
.P==0
DEFSTR(PSP,\<.P>,15,16) ; PACKET.SOURCE.PORT
DEFSTR(PDP,\<.P>,31,16) ; PACKET.DESTINATION.PORT
.P==.P+1
DEFSTR(PSEQ,\<.P>,31,32) ; PACKET.SEQUENCE
.P==.P+1
DEFSTR(PACKS,\<.P>,31,32) ; PACKET.ACK.SEQUENCE
.P==.P+1
DEFSTR(PCTL,\<.P>,35,36) ; Word containing control flags
; Substructures and overlays for above:
DEFSTR(PTDO,\<.P>,3,4) ; PACKET.TCP.DATAOFFSET ( 32-BIT UNITS)
; 4 Unused bits
DEFSTR(PTCTL,\<.P>,15,8) ; PACKET.TCP.CONTROLS
; 2 Unsed bits
DEFSTR(PURG,\<.P>,10,1) ; PACKET.CONTROL.URGENT
DEFSTR(PACK,\<.P>,11,1) ; PACKET.CONTROL.ACK
DEFSTR(PEOL,\<.P>,12,1) ; PACKET.CONTROL.EOL
DEFSTR(PRST,\<.P>,13,1) ; PACKET.CONTROL.RST
DEFSTR(PSYN,\<.P>,14,1) ; PACKET.CONTROL.SYN
DEFSTR(PFIN,\<.P>,15,1) ; PACKET.CONTROL.FIN
DEFSTR(PWNDO,\<.P>,31,16) ; PACKET.WINDOW
.P==.P+1
DEFSTR(PTCKS,\<.P>,15,16) ; PACKET.CHECKSUM
DEFSTR(PURGP,\<.P>,31,16) ; PACKET.URGENT.POINTER
.P==.P+1
MINTHS==4*.P ; Minimum TCP header size (bytes)
; TCP Options (if any) are here:
;MINTOS==10 ; Minimum # Option bytes to cope with
MAXTOS==<.RTJST(-1,PTDO)*4-MINTHS> ; Maximum # Option bytes possible
; Derive some useful numbers from the above:
TCPNPW==PKTELI+.RTJST(-1,PIDO)+.RTJST(-1,PTDO)+<<<1←↑D<WID(PIPL)-WID(PIFO)>>+3>/4>
; Local info + IP + TCP + fragment = Minimum TCP packet, Words
;MAXDSZ==4*<<M2+3>/4>-<4*<<MINIHS+3>/4>>-<4*<<MINTHS+3>/4>>
; Max. number of TCP data bytes
;MINPLN==4*<PKTELI+17+17> ; Maximum packet header length
;MINDSZ==MAXDSZ-<4*<<MINIOS+3>/4>>-<4*<<MINTOS+3>/4>>
; Min. number of bytes per Pkt estimated
;MINPSZ==PKTELI+<<MINIHS+3>/4>+<<MINIOS+3>/4>+<<MINTHS+3>/4>+<<MINTOS+3>/4>
; Options: Two cases.
; Case 1: A single byte of option code
; ENDOPT is and must be 0. This marks the end of the option list.
; NOPOPT is and must be 1. This is one byte long and has no purpose.
; Case 2: General form of options is 1 byte of "kind", 1 byte of total
; length, and N-2 bytes of data, where N is read from the length byte.
; All options are included under the appropriate checksum.
; END End of options ENDOPT
; NOP Filler NOPOPT
; MSL Maximul Segment Length MSLOPT,4,len,gth
; LBL Packet Label LBLOPT,4,seg,id
; RBS Receive Buffer Size RBSOPT,4,bfr,lth
; LTS Local Timestamp LTSOPT,6,t,i,m,e
; General TCP Option generation macro
DEFINE TCPOPTS (USER,RECV,ECHO)<
OPTION(I,END,,↑D0,↑D1,USER,RECV,ECHO)
OPTION(I,NOP,,↑D1,↑D1,USER,RECV,ECHO)
OPTION(T,MSL,,↑D2,↑D4,USER,RECV,ECHO)
OPTION(T,LBL,,↑D33,↑D4,USER,RECV,ECHO)
; OPTION(T,RBS,,↑D37,↑D4,USER,RECV,ECHO)
; OPTION(T,LTS,,↑D132,↑D6,USER,RECV,ECHO)
> ; End of DEFINE TCPOPTS
; Define Option Names
DEFINE OPTION(TYPE,NAME,COPY,NUMBER,LENGTH,USER,RECV,ECHO)<
IFDIF <COPY>,<C>,< NAME'OPT==NUMBER >
IFIDN <COPY>,<C>,< NAME'OPT==CPYOPT+NUMBER >
>
TCPOPTS
; TCB (internal connection block) structure:
TCBQ==<.T==0> ; TCB Queue (TCBH, DeadQ, etc)
TCBLCK==<.T==.T+QSZ> ; TCB.LOCK
.T==.T+LOCKSZ
DEFSTR(TOWNR,\<.T>,17,18) ; TCB.OWNER (job #)
DEFSTR(TJCN,\<.T>,35,18) ; TCB.JCN (n of JCNTCB+n)
.T=.T+1
DEFSTR(TFH,\<.T>,35,36) ; TCB.FH
DEFSTR(TFHC,\<.T>,6,3) ; TCB.FH.NET-CLASS
; TCB.FH.NET (0 => TWLDN=1)
.T=.T+1 ; TCB.FH.TCP (0 => TWLDT=1)
DEFSTR(TLH,\<.T>,35,36) ; TCB.LH
.T=.T+1
DEFSTR(TFP,\<.T>,35,36) ; TCB.FP *** (0 => TWLDP=1)
.T=.T+1
DEFSTR(TLP,\<.T>,35,36) ; TCB.LP *** only 16 bits
.T=.T+1
;DEFSTR(TFLAG,\<.T>,20,21) ; TCB.Flags
; Substructures for the above:
DEFSTR(TERR,\<.T>,7,8) ; TCB.ERROR
DEFSTR(TWLDN,\<.T>,8,1) ; OPEN with Net wild
DEFSTR(TWLDT,\<.T>,9,1) ; OPEN with TCP wild
DEFSTR(TWLDP,\<.T>,10,1) ; OPEN with Port wild
DEFSTR(TSFP,\<.T>,11,1) ; TCB.SEND.FORCE-PACKET
DEFSTR(TSEP,\<.T>,12,1) ; TCB.SEND.ENCOURAGE-PACKET
; DEFSTR(TRPB,\<.T>,13,1) ; TCB.RECV.PARTIAL-BUFFER
DEFSTR(TRPP,\<.T>,14,1) ; TCB.RECV.PARITAL-PACKET
DEFSTR(TSCR,\<.T>,15,1) ; TCB.SECURE-CONNECTION
DEFSTR(TTVT,\<.T>,16,1) ; TCB.TCP-Virtual-terminal
DEFSTR(TSAP,\<.T>,17,1)
DEFSTR(TERRT,\<.T>,20,1) ; TCB.ERROR.TRACE
DEFSTR(TSTAT,\<.T>,35,15) ; TCB.STATE
; Overlays for above
DEFSTR(TRSYN,\<.T>,23,3) ; TCB.STATE.RECV-SYNC
DEFSTR(TSSYN,\<.T>,26,3) ; TCB.STATE.SEND-SYNC
; State codes for connections (in TRSYN and TSSYN):
SYNABL==4 ; SYNCHABLE: Activated by user call
SYNSNT==<SYNRCV==5> ; SYN sent or received
SYNCED==7 ; SYN acked
FINSNT==<FINRCV==2> ; FIN sent or received but not ACKd
NOTSYN==0 ; Connection fully closed or not open
DEFSTR(TSUOP,\<.T>,27,1) ; TCB.STATE.USER-OPEN
DEFSTR(TSOPN,\<.T>,28,1) ; TCB.STATE.SAID-OPEN
DEFSTR(TSPRS,\<.T>,29,1) ; TCB.STATE.PERSISTENT
DEFSTR(TSABT,\<.T>,30,1) ; TCB.STATE.ABORT
DEFSTR(TSSV,\<.T>,31,1) ; TCB.STATE.SEQUENCE-VALID
; 2 Unused bits
DEFSTR(TSURG,\<.T>,34,1) ; TCB.SEND.URGENT-MODE
DEFSTR(TRURG,\<.T>,35,1) ; TCB.RECV.URGENT-MODE
; Send variables
.T=.T+1
DEFSTR(TSLFT,\<.T>,35,36) ; TCB.SEND.LEFT
.T=.T+1
DEFSTR(TSSEQ,\<.T>,35,36) ; TCB.SEND.SEQUENCE
.T=.T+1
DEFSTR(TSURP,\<.T>,35,36) ; TCB.SEND.URGENT-POINTER
.T=.T+1
DEFSTR(TSWND,\<.T>,17,18) ; TCB.SEND.WINDOW
DEFSTR(TSCB,\<.T>,35,18) ; TCB.SEND.CURRENT-BUFFER
.T=.T+1
DEFSTR(TSTO,\<.T>,35,36) ; TCB.SEND.TIME-OUT
TCBSBQ==<.T=.T+1> ; TCB.SEND.BUFFER-QUEUE
TCBRXQ==<.T=.T+QSZ> ; TCB.SEND.REXMIT-QUEUE
; Recv variables
.T==.T+QSZ
DEFSTR(TRIS,\<.T>,35,36) ; TCB.RECV.INITIAL-SEQUENCE
.T=.T+1
DEFSTR(TRLFT,\<.T>,35,36) ; TCB.RECV.LEFT
.T=.T+1
DEFSTR(TRURP,\<.T>,35,36) ; TCB.RECV.URGENT-POINTER
.T=.T+1
DEFSTR(TRWND,\<.T>,17,18) ; TCB.RECV.WINDOW
DEFSTR(TRCB,\<.T>,35,18) ; TCB.RECV.CURRENT-BUFFER
.T=.T+1
DEFSTR(TRCBY,\<.T>,35,36) ; TCB.RECV.CURRENT-BYTE
.T=.T+1
DEFSTR(TRBS,\<.T>,35,36) ; TCB.RECV.BUFFER-SPACE
TCBRBQ==<.T=.T+1> ; TCB.RECV.BUFFER-QUEUE
TCBRPQ==<.T=.T+QSZ> ; TCB.RECV.PACKET-QUEUE
; PSI variables
TCBPIC==<.T=.T+QSZ> ; TCB.PSI-CHANNELS
DEFSTR(TPSIC,TCBPIC,35,36) ; All PSI channels
; Overlays for above:
DEFSTR(TPICU,TCBPIC,5,6) ; URGENT DATA ARRIVED
DEFSTR(TPICR,TCBPIC,11,6) ; RECV DONE
DEFSTR(TPICS,TCBPIC,17,6) ; SEND DONE
DEFSTR(TPICE,TCBPIC,23,6) ; ERROR
DEFSTR(TPICX,TCBPIC,29,6) ; STATE CHANGE
DEFSTR(TPICA,TCBPIC,35,6) ; EOL ACK
; Following must have same order as above
TCBPIF==.T+1 ; TCB.PSI-FORKS
DEFSTR(TPIFU,TCBPIF+0,17,18) ; URGENT DATA ARRIVED
DEFSTR(TPIFR,TCBPIF+0,35,18) ; RECV DONE
DEFSTR(TPIFS,TCBPIF+1,17,18) ; SEND DONE
DEFSTR(TPIFE,TCBPIF+1,35,18) ; ERROR
DEFSTR(TPIFX,TCBPIF+2,17,18) ; STATE CHANGE
DEFSTR(TPIFA,TCBPIF+2,35,18) ; EOL ACK
.T==TCBPIF+3
DEFSTR(TOPNF,\<.T>,8,9) ; TCB.OPEN.WAIT FLAG INDEX
DEFSTR(TERRF,\<.T>,17,9) ; TCB.ERROR.FLAG index
DEFSTR(TOFRK,\<.T>,35,18) ; TCB.OWNING-FORK
; Retransmission variables
.T=.T+1
DEFSTR(TSMRT,\<.T>,35,36) ; TCB.SMOOTHED-ROUND-TRIP (or)
DEFSTR(TMNRT,\<.T>,35,36) ; TCB.MIN-ROUND-TRIP
.T=.T+1
DEFSTR(TMXRT,\<.T>,35,36) ; TCB.MAX-ROUND-TRIP
.T=.T+1
DEFSTR(TRXI,\<.T>,35,36) ; TCB.RETRANSMIT-INTERVAL
.T=.T+1
DEFSTR(TRXP,\<.T>,35,36) ; TCB.Retransmission.Parameters
;Substructures of the above:
DEFSTR(TRXPN,\<.T>,8,9) ; Numberator of backoff fraction
DEFSTR(TRXPD,\<.T>,17,9) ; Denominator thereof
DEFSTR(TRXPI,\<.T>,35,18) ; Initial interval
; Queues and wakeup times for various processes:
TCBQRA==<.T=.T+1> ; Reassembler queue
TCBTRA==<.T=.T+QSZ> ; When RA needed
TCBQPZ==<.T=.T+1> ; Packetizer
TCBTPZ==<.T=.T+QSZ>
TCBQRX==<.T=.T+1> ; Retransmitter
TCBTRX==<.T=.T+QSZ>
TCBQDG==<.T=.T+1> ; Delay Actions
TCBTDG==<.T=.T+QSZ>
.T==.T+1
DEFSTR(TIFDF,\<.T>,0,1) ; IP Don't-Fragment flag
DEFSTR(TTTL,\<.T>,8,8) ; IP Time-to-live
; 1 Unused bit
DEFSTR(TTOS,\<.T>,17,8) ; IP Type-of-service
DEFSTR(TABTFX,\<.T>,35,18) ; Forkx of ABORTER
.T=.T+1
DEFSTR(TSLVN,\<.T>,17,18) ; Next Security level
DEFSTR(TSLVC,\<.T>,35,18) ; Current Security Level
.T=.T+1
; 2 bits really unused
DEFSTR(TOPFP,\<.T>,17,18) ; Foreign port at open
DEFSTR(TNUFM,\<.T>,18,1) ; OPENed with new formats
; 8 unused bits
DEFSTR(TVTL,\<.T>,35,9) ; Virtual terminal line number
.T=.T+1
DEFSTR(TOPFH,\<.T>,35,36) ; TCB.OPEN-FH
.T=.T+1
DEFSTR(TOPLH,\<.T>,35,36) ; TCB.OPEN-LH
.T=.T+1
DEFSTR(TSBYT,\<.T>,35,36) ; Bytes left to send
.T=.T+1
DEFSTR(TRLAK,\<.T>,35,36) ; Seq # of last PACKS sent
.T=.T+1
DEFSTR(TRLWN,\<.T>,35,36) ; Seq # of last PWNDO sent or -1
.T=.T+1
DEFSTR(TSMXB,\<.T>,35,36) ; Max send rate
.T=.T+1
DEFSTR(TSMXP,\<.T>,35,36) ; Max send packet length (inc header)
; Option Variables
.T=.T+1
DEFSTR(TIPDO,\<.T>,5,4) ;TEMP ; IP Data offset, words
DEFSTR(TIPOR,\<.T>,11,6) ; IP Received options, bytes
DEFSTR(TIPOU,\<.T>,17,6) ; IP User options, bytes
DEFSTR(TIOPF,\<.T>,35,18) ; IP User option flags
.T=.T+1
DEFSTR(TTPDO,\<.T>,5,4) ;TEMP ; TCP Data offset, words
DEFSTR(TTPOR,\<.T>,11,6) ; TCP Received options, bytes
DEFSTR(TTPOU,\<.T>,17,6) ; TCP User options, bytes
DEFSTR(TTOPF,\<.T>,35,18) ; TCP User option flags
TCBIO==<.T=.T+1> ;TEMP ; IP Option list (send)
TCBIR==<.T=.T+<MAXIOS+3>/4> ; Last IP Options received
TCBIU==<.T=.T+<MAXIOS+3>/4> ; IP Options from User
TCBTO==<.T=.T+<MAXIOS+3>/4> ;TEMP ; TCP Option list (send)
TCBTR==<.T=.T+<MAXTOS+3>/4> ; Last TCP Options received
TCBTU==<.T=.T+<MAXTOS+3>/4> ; TCP Options from User
.T=.T+<MAXTOS+3>/4
DEFSTR(TERBF,\<.T>,17,18) ; Error/Trace (user) buffer adr
DEFSTR(TERJN,\<.T>,35,18) ; Error/trace (user) JFN
.T=.T+1
DEFSTR(TCTBS,\<.T>,17,18) ; Count of no-buffer errors
DEFSTR(TCTSQ,\<.T>,35,18) ; Count of sequence # pauses
.T=.T+1
DEFSTR(TSCPK,\<.T>,35,36) ; Send current packet
.T=.T+1 ; Spare
TCBSIZ==.T+1 ; Size of a TCB
PURGE .T
; The following definition must match that in TTTVDV.MAC
IFNKA < TTNETW==4 > ; (i.e. TTDEV)
IFKA < EXTERN TTNETW >
DEFSTR(PTVT,TTNETW,35,18) ; Holds pointer to TVT's TCB
; Flag bit definitions: (Now in MONSYM)
IFNDEF TCP%ER,< PRINTX % TCP Buffer header flag bits not defined in MONSYM
TCP%ER==1B0 ; ERROR
TCP%LE==1B1 ; Local error flag (0 is remote)
TCP%PE==1B2 ; Permanent error (0 is temporary)
TCP%EC==37B7 ; Error code w/o flags
TCP%DN==1B12 ; DONE
TCP%UR==1B15 ; URGENT DATA
TCP%EL==1B16 ; obsolete ; PUSH
TCP%PU==1B16 ; PUSH
TCP%WM==1B17 ; WORD MODE
.TCPBF==0 ; Buffer Flags
.TCPBA==1 ; Buffer data address
.TCPBC==2 ; Buffer data count
.TCPBO==3 ; Buffer option addresses
.TCPOW==↑D10 ; Buffer option address word count
.TCPBI==4 ; Buffer IP info
.TCPBS==5 ; Buffer header size
>
; CHKARG stack parameter block definitions
; Caller Callee
; STACKL <<ARGBLK,CHKADW>,...>
; CHKADL <<locals>> CHKADL <<locals>>
; ...code... ...code...
; CHKADR CHKADR
DEFINE CHKADL (LOCL)<
IFB <LOCL>,< LOCAL <PARAMS> >
IFNB <LOCL>,< LOCAL <PARAMS,LOCL> >
LALL
DEFINE LH<0(PARAMS)>
DEFINE LP<1(PARAMS)>
DEFINE FH<2(PARAMS)>
DEFINE FP<3(PARAMS)>
DEFINE JCN<4(PARAMS)>
DEFINE WILDOK<5(PARAMS)>
DEFINE FN<6(PARAMS)>
DEFINE ARG1<7(PARAMS)>
DEFINE ARG2<10(PARAMS)>
SALL
> ; End of DEFINE CHKADL
CHKADW==11
DEFINE CHKADR <
PURGE LH,LP,FH,FP,JCN,WILDOK,FN,ARG1,ARG2
RESTORE
> ; End of CHKADR
; BUFFER Structure:
BFRQ==<.B==0> ; BUFFER QUEUE, LH contains flags
BFRSUI==<.B==.B+QSZ> ; BUFFER START USER INFORMATION
; Offsets defined in MONSYM
BFRFLG==BFRSUI+.TCPBF ; BUFFER FLAG WORD
DEFSTR(BURG,BFRFLG,↑L<TCP%UR>,1); BUFFER URGENT
DEFSTR(BEOL,BFRFLG,↑L<TCP%PU>,1); BUFFER END-OF-LETTER
DEFSTR(BWM,BFRFLG,↑L<TCP%WM>,1) ; BUFFER WORD-MODE
BFRDAD==BFRSUI+.TCPBA
DEFSTR(BDADR,BFRDAD,35,36) ; BUFFER DATA ADDRESS
BFRCNT==BFRSUI+.TCPBC
DEFSTR(BCNT,BFRCNT,35,36) ; BUFFER.COUNT
BFROPT==BFRSUI+.TCPBO
;
BFREUI==<.B==BFRSUI+.TCPBS> ; BUFFER END USER INFO
DEFSTR(BHADR,\<.B>,35,36) ; BUFFER HEADER ADDRESS
.B==.B+1
DEFSTR(BICNT,\<.B>,35,36) ; BUFFER INITIAL COUNT
.B==.B+1
DEFSTR(BFRKX,\<.B>,17,18) ; BUFFER.FORKX
DEFSTR(BUPAG,\<.B>,35,18) ; BUFFER.USER PAGE
.B==.B+1
DEFSTR(BBLIP,\<.B>,17,18) ; BUFFER.BYTESLEFTINPAGE
DEFSTR(BMPAG,\<.B>,35,18) ; BUFFER.MONITORPAGE
BFRPTR==<.B==.B+1>
DEFSTR(BPTR,BFRPTR,35,36) ; BUFFER POINTER
; Overlays for above:
DEFSTR(BPTRP,BFRPTR,5,6) ; Size field
DEFSTR(BPTRS,BFRPTR,11,6) ; Position field
DEFSTR(BPTRA,BFRPTR,35,18) ; Address field
.B==.B+1
DEFSTR(BTCB,\<.B>,17,18) ; BUFFER.TCB
DEFSTR(BIDX,\<.B>,35,18) ; BUFFER.INDEX
.B==.B+1
DEFSTR(BTS,\<.B>,35,36) ; BUFFER.TIMESTAMP
BFRSIZ==.B+1
; AC1 Bits for TCP JSYSs (Now in MONSYM)
IFNDEF TCP%JS,< PRINTX % TCP JSYS flag bits not defined in MONSYM
TCP%JS==1B0 ; JCN Supplied
TCP%WT==1B1 ; Wait for completion
TCP%FS==1B5 ; Force Synchronization (active open)
TCP%PS==1B6 ; Persistent open
TCP%ST==1B7 ; Return statistics (STAT)
TCP%SY==1B8 ; Symbolic name list given (STAT)
TCP%SC==1B8 ; Secure connection (OPEN, SEND)
TCP%HP==1B9 ; High priority (OPEN, SEND)
TCP%VT==1B10 ; TCP Virtual Terminal (OPEN)
TCP%TV==1B11 ; TVT Supplied (STAT)
TCP%NT==1B12 ; Return AOBJN pointer over TVTs (STAT)
TCP%IX==1B13 ; Connection index supplied (STAT)
TCP%NI==1B14 ; Return AOBJN pointer over connections (STAT)
TCP%SD==1B15 ; Return STAT definitions instead of values (STAT)
TCP%ET==1B16 ; ERROR info flag
TCP%PT==1B17 ; Packet trace flag
.TCPLH==0 ; Connection Local Host (0 is wild)
.TCPLP==1 ; Connection Local Port (0 is illegal)
.TCPFH==2 ; Connection Foreign Host (0 is wild)
.TCPFP==3 ; Connection Foreign Port (0 is wild)
.TCPOP==4 ; Connection Option addresses
.TCPOW==↑D10 ; Connection Option address word count
.TCPIP==5 ; Connection IP parameters (Flag=3B1, TTL=377B17, TOS=377B35)
.TCPCS==6 ; Connection block word size
>
; Event codes:
E.BIT==200 ; ERROR bit
L.BIT==100 ; LOCAL condition bit
P.BIT==040 ; PERMANENT condition bit
OK==0*E.BIT+0*L.BIT+0*P.BIT ; General success code
XFT==0*L.BIT+0*P.BIT ; Temporary Foreign condition
XFP==0*L.BIT+1*P.BIT ; Permanent Foreign condition
XLP==1*L.BIT+1*P.BIT ; Permanent Local condition
EFT==1*E.BIT+0*L.BIT+0*P.BIT ; Temporary Foreign Error
EFP==1*E.BIT+0*L.BIT+1*P.BIT ; Permanent Foreign Error
ELT==1*E.BIT+1*L.BIT+0*P.BIT ; Temporary Local Error
ELP==1*E.BIT+1*L.BIT+1*P.BIT ; Permanent Local Error
; Other codes:
IGN==100 ; Packet is to be ignored
DUP==10 ; Packet is a duplicate (in TCPIP)
ERR==1 ; Packet is in error (in TCPIP)
; Process block
PRCQ==0 ; (Ext) ptr to input queue head (TCBs, etc)
PRCLCK==1 ; Lock
.F==PRCLCK+LOCKSZ
PRCROU==.F ; (Ext) address of routine
PRCWAK==.F+1 ; -1 or TODCLK of wakeup
PRCQOF==.F+2 ; TCB,,m Pointer to queue in TCB
PRCWOF==.F+3 ; TCB,,n Pointer to wakeup in TCB
PRCSGT==.F+4 ; TODCLK of most recent signal
PRCRNC==.F+5 ; Pointer to run counter xxRNCT
PRCTMR==.F+6 ; Pointer to timer xxUSE
PROCSZ==.F+7 ; Size of a process block
; Macro which expands into code to cause a process to run after
; a specified delay. The interesting case is 0 delay in which
; the routine may be called directly, without the overhead of locking
; and unlocking the process Q twice, and locking the TCB again etc.
DEFINE $SIGNL(TPROC,DELTA,%TAGQ,%TAGX)<
XMOVEI T1,TPROC ; Process to signal
IFNKA <
IFE DELTA,<
MOVE T3,TODCLK ; Now
SKIPL T2,PRCWAK(T1) ; If no wakeup set, NOW is ok
CAMLE T2,T3 ; If past due, queue
SKIPLE NSKED ; NOW is ok unless NOSKED
JRST %TAGQ ; No. Get in Q for FIFO behavior
PUSH P,PROC ; Do it NOW
MOVEM T3,PRCSGT(T1) ; TODCLK of most recent SIGNAL
CALL TCPTSK ; Call the task
POP P,PROC ; Restore our ID as running process
JRST %TAGX ; All done
%TAGQ: >> ;IFE DELTA, IFNKA
; Avoid stack overflow on KA, always queue
MOVX T2,DELTA ; Number of milliseconds
CALL SIGNAL
IFNKA <
IFE DELTA,<
%TAGX: >>
> ; end DEFINE $